using System;
using System.Linq;
using Csla;
using Csla.Data;
using Presupuestos.Datos;
using System.ComponentModel.DataAnnotations;

namespace Presupuestos.Negocio.Editables
{
    [Serializable]
    public class Usuario : BusinessBase<Usuario>
    {
        #region Business Methods

        public static readonly PropertyInfo<string> m_ID = RegisterProperty<string>(c => c.Id);
        public string Id
        {
            get { return GetProperty(m_ID); }
            set { SetProperty(m_ID, value); }
        }

        public static readonly PropertyInfo<string> m_Nombre = RegisterProperty<string>(c => c.Nombre);
        [Required()]
        public string Nombre
        {
            get { return GetProperty(m_Nombre); }
            set { SetProperty(m_Nombre, value); }
        }

        public static readonly PropertyInfo<string> m_Descripcion = RegisterProperty<string>(c => c.Descripcion);
        [Required()]
        public string Descripcion
        {
            get { return GetProperty(m_Descripcion); }
            set { SetProperty(m_Descripcion, value); }
        }

        public static readonly PropertyInfo<DateTime> m_FechaActivacion = RegisterProperty<DateTime>(c => c.FechaActivacion);
        public DateTime FechaActivacion
        {
            get { return GetProperty(m_FechaActivacion); }
            set { SetProperty(m_FechaActivacion, value); }
        }

        public static readonly PropertyInfo<bool> m_Vigencia = RegisterProperty<bool>(c => c.Vigencia);
        public bool Vigencia
        {
            get { return GetProperty(m_Vigencia); }
            set { SetProperty(m_Vigencia, value); }
        }

        #endregion

        #region Business Rules

        protected override void AddBusinessRules()
        {
            // TODO: add validation rules
            base.AddBusinessRules();

            //BusinessRules.AddRule(new Rule(IdProperty));
        }

        private static void AddObjectAuthorizationRules()
        {
            // TODO: add authorization rules
            //BusinessRules.AddRule(...);
        }

        #endregion

        #region Factory Methods

        public static Usuario NewUsuario()
        {
            return DataPortal.Create<Usuario>();
        }

        public static Usuario GetUsuario(string id)
        {
            return DataPortal.Fetch<Usuario>(id);
        }

        public static void DeleteUsuario(string id)
        {
            DataPortal.Delete<Usuario>(id);
        }

        private Usuario()
        { /* Require use of factory methods */ }

        #endregion

        #region Data Access

        [RunLocal]
        protected override void DataPortal_Create()
        {
            using (BypassPropertyChecks)
            {
                Id = Guid.NewGuid().ToString();
                FechaActivacion = DateTime.Now;
                Vigencia = true;
            }
        }

        private void DataPortal_Fetch(string criteria)
        {
            using (var ctx = ObjectContextManager<PresupuestosEntities>.
                GetManager("PresupuestosEntities"))
            {
                using (BypassPropertyChecks)
                {
                    var q = (from usr in ctx.ObjectContext.Usuarios
                             where usr.IdUsuario == criteria
                             select usr).Single();
                    Id = q.IdUsuario;
                    Nombre = q.NombreUsuario;
                    Descripcion = q.Descripcion;
                    FechaActivacion = q.FechaActivacion;
                    Vigencia = q.FlagVigencia;
                    MarkOld();
                    BusinessRules.CheckRules();
                }
            }

        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Insert()
        {
            using (var ctx = ObjectContextManager<PresupuestosEntities>.
                GetManager("PresupuestosEntities"))
            {
                using (BypassPropertyChecks)
                {
                    var nuevoUsuario = new UsuarioData();
                    DoInsertUpdate(nuevoUsuario);
                    ctx.ObjectContext.Usuarios.AddObject(nuevoUsuario);
                    ctx.ObjectContext.SaveChanges();
                }
            }
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Update()
        {
            using (var ctx = ObjectContextManager<PresupuestosEntities>.
             GetManager("PresupuestosEntities"))
            {
                using (BypassPropertyChecks)
                {
                    var q = (from usr in ctx.ObjectContext.Usuarios
                             where usr.IdUsuario == Id
                             select usr).Single();

                    DoInsertUpdate(q);

                    ctx.ObjectContext.SaveChanges();

                }
            }
        }

        private void DoInsertUpdate(UsuarioData obj)
        {
            obj.IdUsuario = Id;
            obj.NombreUsuario = Nombre;
            obj.Descripcion = Descripcion;
            obj.FechaActivacion = FechaActivacion;
            obj.FlagVigencia = Vigencia;
            obj.EstadoRegistro = true;
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(this.Id);
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        private void DataPortal_Delete(string criteria)
        {
            using (var ctx = ObjectContextManager<PresupuestosEntities>.
             GetManager("PresupuestosEntities"))
            {
                using (BypassPropertyChecks)
                {
                    var q = (from usr in ctx.ObjectContext.Usuarios
                             where usr.IdUsuario == criteria
                             select usr).Single();

                    ctx.ObjectContext.Usuarios.DeleteObject(q);
                    ctx.ObjectContext.SaveChanges();
                }
            }
        }

        #endregion
    }
}
